package gov.dhs.cis.soa.generators;

import gov.dhs.cis.soa.SOAData;
import gov.dhs.cis.soa.readers.AgentsLayerReader;
import gov.dhs.cis.soa.readers.ApplicationReader;
import gov.dhs.cis.soa.readers.BusProcessLayerReader;
import gov.dhs.cis.soa.readers.DataClassReader;
import gov.dhs.cis.soa.readers.InfrastructureLayerReader;
import gov.dhs.cis.soa.readers.IntegrationLayerReader;
import gov.dhs.cis.soa.readers.InterfacesReader;
import gov.dhs.cis.soa.readers.Process2EntitiesRefReader;
import gov.dhs.cis.soa.readers.ProcessLayerReader;
import gov.dhs.cis.soa.readers.RulesLayerReader;
import gov.dhs.cis.soa.readers.SecurityCompReader;
import gov.dhs.cis.soa.readers.ServicesLayerReader;
import gov.dhs.cis.soa.readers.reqpro.RolesReader;
import gov.dhs.cis.soa.readers.reqpro.UseCasesReader;

import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.w3c.dom.Document;



public class EADocumentPersistor {
	static final Logger loger = Logger.getLogger(EADocumentPersistor.class);

	private SOAData soaData = new SOAData();
	
	public void prepareData() {
		// TODO Auto-generated method stub
		SecurityCompReader scReader = new SecurityCompReader();
		soaData = scReader.extractSecComponents(soaData);
		loger.debug("Extracted SecurityComp:" + soaData.secCompList.size());
		
		ApplicationReader appReader = new ApplicationReader();
		soaData = appReader.extractApplications(soaData);
		loger.debug("Extracted Applications:" + soaData.appList.size());
		
		IntegrationLayerReader integReader = new IntegrationLayerReader();
		soaData = integReader.extractAll(soaData);
		loger.debug("Extracted Integration Comp: SW-" + soaData.intSWList.size() + ", UC-" + soaData.intCompList.size());

		InfrastructureLayerReader infReader = new InfrastructureLayerReader();
		soaData = infReader.extractAll(soaData);
		loger.debug("Extracted Infrastructure Comp: LS-" + soaData.infLSList.size() + ", PS-" + soaData.infPSList.size());

		RolesReader aReader = new RolesReader();
		soaData = aReader.extractRoles(soaData);
		loger.debug("Extracted Actors:" + soaData.actorList.size());

		DataClassReader dReader = new DataClassReader();
		soaData = dReader.extractDataClasses(soaData);
		loger.debug("Extracted DataClasses:" + soaData.dataList.size());
		
		AgentsLayerReader agReader = new AgentsLayerReader();
		soaData = agReader.extractAgents(soaData);
		loger.debug("Extracted Agents:" + soaData.agentList.size());

		UseCasesReader uReader = new UseCasesReader();
		soaData = uReader.extractUseCases(soaData);
		loger.debug("Extracted UseCases:" + soaData.useCaseList.size());
		
		ProcessLayerReader pReader = new ProcessLayerReader();
		soaData = pReader.extractProcess(soaData);
		loger.debug("Extracted Processes:" + soaData.procList.size());
		
		ServicesLayerReader sReader = new ServicesLayerReader();
		soaData = sReader.extractServices(soaData);
		loger.debug("Extracted Services:" + soaData.servList.size());
		
		InterfacesReader iReader = new InterfacesReader();
		soaData = iReader.extractInterfaces(soaData);
		loger.debug("Extracted Interfaces:" + soaData.intList.size());
		
		Process2EntitiesRefReader prefReader = new Process2EntitiesRefReader();
		soaData = prefReader.extractProcess2Entities(soaData);
		loger.debug("Extracted Enties to Processes:" + soaData.procList.size());

		BusProcessLayerReader bProcReader = new BusProcessLayerReader();
		soaData = bProcReader.extractBusinessProcs(soaData);
		loger.debug("Extracted Enties to Business Processes:" + soaData.bProcessList.size());

		//at the end read service Operations, this keeps the old imported model id nums in sync with newer model.
		soaData = sReader.extractServiceOperations(soaData);
		loger.debug("Extracted Services Operations.");
		
		soaData.resolveAllDependices();
	}

	public void prepareRuleData() {
		// TODO Auto-generated method stub
		RulesLayerReader rsReader = new RulesLayerReader();
		soaData = rsReader.extractRuleSets(soaData);
		loger.debug("Extracted RuleSet:" + soaData.rSetsList.size());
	}
	
	public void write2UML(String outputDir) {
		UMLFileCreator creator = new UMLFileCreator(soaData, outputDir);
		creator.createUMLFile();		
	}

	public void doWrite(String outputDir) {
		write2UML(outputDir);
	}

	public void initLog4J() {
		try {
			String fileName = "log4j.xml";
			InputStream stream = this.getClass().getClassLoader().getResourceAsStream(fileName);
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			docFactory.setValidating(false);
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
			Document doc = docBuilder.parse(stream);
	        DOMConfigurator conf = new DOMConfigurator();
	        conf.doConfigure(doc.getDocumentElement(), LogManager.getLoggerRepository());
//	        DOMConfigurator conf = new DOMConfigurator();
//	        conf.doConfigure(fileName, null);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if( args.length != 1 )
            throw new Error("USAGE: java EADocumentPersistor outputFolder");
		
		EADocumentPersistor persistor = new EADocumentPersistor();
		persistor.initLog4J();
		//to load all the service, processes ... org arch xsl sheets
		//persistor.prepareData();
		
		//to load all the process rules & RCT rules xsl sheets
		persistor.prepareRuleData();
		
		persistor.doWrite(args[0]);
	}

}
